//! # 网关核心Trait定义
//!
//! 定义网关系统的核心接口契约，实现面向接口编程。

use async_trait::async_trait;
use std::sync::Arc;
use crate::core::{GatewayRequest, GatewayResponse, GatewayResult, GatewayContext};
// 使用rustcloud-core中的统一ServiceRegistry接口
use rustcloud_core::{ServiceRegistry, ServiceInstance};

/// 网关处理器核心接口
/// 
/// 定义网关请求处理的核心契约，所有网关实现都必须遵循此接口。
#[async_trait]
pub trait GatewayHandler: Send + Sync {
    /// 处理网关请求
    /// 
    /// # 参数
    /// * `request` - 网关请求对象
    /// * `context` - 请求处理上下文
    /// 
    /// # 返回值
    /// 返回处理结果或错误
    async fn handle(&self, request: GatewayRequest, context: Arc<GatewayContext>) -> GatewayResult<GatewayResponse>;
    
    /// 获取处理器名称
    fn name(&self) -> &str;
    
    /// 检查处理器健康状态
    async fn health_check(&self) -> bool;
}

/// 中间件接口
/// 
/// 定义网关中间件的处理契约，支持请求预处理和响应后处理。
#[async_trait]
pub trait Middleware: Send + Sync {
    /// 处理请求前置逻辑
    /// 
    /// # 参数
    /// * `request` - 网关请求对象
    /// * `context` - 请求处理上下文
    /// 
    /// # 返回值
    /// 返回处理后的请求或错误
    async fn before_request(&self, request: GatewayRequest, context: Arc<GatewayContext>) -> GatewayResult<GatewayRequest>;
    
    /// 处理响应后置逻辑
    /// 
    /// # 参数
    /// * `response` - 网关响应对象
    /// * `context` - 请求处理上下文
    /// 
    /// # 返回值
    /// 返回处理后的响应或错误
    async fn after_response(&self, response: GatewayResponse, context: Arc<GatewayContext>) -> GatewayResult<GatewayResponse>;
    
    /// 获取中间件名称
    fn name(&self) -> &str;
    
    /// 获取中间件优先级（数值越小优先级越高）
    fn priority(&self) -> i32 {
        100
    }
}

/// Gateway Service Discovery Manager
/// 
/// 网关专用的服务发现管理器，复用rustcloud-core中的ServiceRegistry trait
/// 提供网关特有的缓存、路由和健康检查功能
pub struct GatewayServiceDiscoveryManager {
    /// 底层服务注册中心（复用rustcloud-core接口）
    registry: Arc<dyn ServiceRegistry>,
    /// 网关路由缓存
    route_cache: Arc<tokio::sync::RwLock<std::collections::HashMap<String, Vec<ServiceInstance>>>>,
    /// 缓存过期时间
    cache_ttl: std::time::Duration,
}

impl GatewayServiceDiscoveryManager {
    /// 创建新的网关服务发现管理器
    pub fn new(registry: Arc<dyn ServiceRegistry>) -> Self {
        Self {
            registry,
            route_cache: Arc::new(tokio::sync::RwLock::new(std::collections::HashMap::new())),
            cache_ttl: std::time::Duration::from_secs(300), // 5分钟缓存
        }
    }

    /// 发现服务实例（带缓存）
    pub async fn discover_service(&self, service_name: &str) -> GatewayResult<Vec<ServiceInstance>> {
        // 先检查缓存
        if let Some(cached_instances) = self.get_cached_instances(service_name).await {
            return Ok(cached_instances);
        }

        // 缓存未命中，从注册中心获取
        let instances = self.registry.discover(service_name).await
            .map_err(|e| crate::core::GatewayError::ServiceDiscovery {
                message: e.to_string(),
                service_name: service_name.to_string(),
            })?;

        // 更新缓存
        self.update_cache(service_name, instances.clone()).await;

        Ok(instances)
    }

    /// 获取缓存的实例
    async fn get_cached_instances(&self, service_name: &str) -> Option<Vec<ServiceInstance>> {
        let cache = self.route_cache.read().await;
        cache.get(service_name).cloned()
    }

    /// 更新缓存
    async fn update_cache(&self, service_name: &str, instances: Vec<ServiceInstance>) {
        let mut cache = self.route_cache.write().await;
        cache.insert(service_name.to_string(), instances);
    }

    /// 清除缓存
    pub async fn clear_cache(&self) {
        let mut cache = self.route_cache.write().await;
        cache.clear();
    }
}

/// 负载均衡接口
/// 
/// 定义负载均衡策略的统一接口。
#[async_trait]
pub trait LoadBalancer: Send + Sync {
    /// 选择服务实例
    /// 
    /// # 参数
    /// * `service_name` - 服务名称
    /// * `instances` - 可用实例列表
    /// * `context` - 请求上下文
    /// 
    /// # 返回值
    /// 返回选中的服务实例
    async fn select(&self, service_name: &str, instances: &[ServiceInstance], context: Arc<GatewayContext>) -> GatewayResult<Option<ServiceInstance>>;
    
    /// 报告实例调用结果
    /// 
    /// # 参数
    /// * `instance` - 服务实例
    /// * `success` - 是否调用成功
    /// * `response_time` - 响应时间
    async fn report(&self, instance: &ServiceInstance, success: bool, response_time: u64);
}

// ServiceInstance已经从rustcloud-core导入，无需重复定义
// 如果需要网关特有的扩展，可以创建包装类型

/// 网关路由实例信息（扩展ServiceInstance）
#[derive(Debug, Clone)]
pub struct GatewayRouteInstance {
    /// 基础服务实例
    pub service_instance: ServiceInstance,
    /// 路由权重
    pub route_weight: i32,
    /// 路由路径
    pub route_path: Option<String>,
    /// 是否启用SSL
    pub ssl_enabled: bool,
    /// 最后健康检查时间
    pub last_health_check: Option<chrono::DateTime<chrono::Utc>>,
}

impl From<ServiceInstance> for GatewayRouteInstance {
    fn from(instance: ServiceInstance) -> Self {
        Self {
            service_instance: instance,
            route_weight: 100,
            route_path: None,
            ssl_enabled: false,
            last_health_check: None,
        }
    }
}

impl GatewayRouteInstance {
    /// 获取实例地址
    pub fn address(&self) -> String {
        format!("{}:{}", self.service_instance.host, self.service_instance.port)
    }

    /// 获取路由URL
    pub fn route_url(&self, path: &str) -> String {
        let protocol = if self.ssl_enabled { "https" } else { "http" };
        let base_path = self.route_path.as_deref().unwrap_or("");
        format!("{}://{}{}{}", protocol, self.address(), base_path, path)
    }
}